home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / XML / Beautifier / Tokenizer.php < prev   
PHP Script  |  2004-03-24  |  11KB  |  372 lines

  1. <?PHP
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2002 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stephan Schmidt <schst@php.net>                             |
  17. // +----------------------------------------------------------------------+
  18.  
  19. /**
  20.  * XML/Beautifier/Tokenizer.php
  21.  *
  22.  * @category XML
  23.  * @package  XML_Beautifier
  24.  * @author   Stephan Schmidt <schst@php.net>
  25.  * @todo     tokenize DTD
  26.  * @todo     check for xml:space attribute
  27.  */
  28.  
  29. /**
  30.  * XML_Parser is needed to parse the document
  31.  */
  32. require_once 'XML/Parser.php';
  33.  
  34. /**
  35.  * Tokenizer for XML_Beautifier
  36.  *
  37.  * This class breaks an XML document in seperate tokens
  38.  * that will be rendered by an XML_Beautifier renderer.
  39.  *
  40.  * @category XML
  41.  * @package  XML_Beautifier
  42.  * @author   Stephan Schmidt <schst@php.net>
  43.  */
  44. class XML_Beautifier_Tokenizer extends XML_Parser {
  45.  
  46.    /**
  47.     * current depth
  48.     * @var    integer
  49.     * @access private
  50.     */
  51.     var $_depth = 0;
  52.  
  53.    /**
  54.     * stack for all found elements
  55.     * @var    array
  56.     * @access private
  57.     */
  58.     var $_struct = array();
  59.  
  60.    /**
  61.     * current parsing mode
  62.     * @var    string
  63.     * @access private  
  64.     */
  65.     var $_mode = "xml";
  66.     
  67.    /**
  68.     * Tokenize a document
  69.     *
  70.     * @param    string  $document   filename or XML document
  71.     * @param    boolean $isFile     flag to indicate whether the first parameter is a file
  72.     */
  73.     function tokenize( $document, $isFile = true )
  74.     {
  75.         $this->folding = false;
  76.         $this->XML_Parser();
  77.         $this->_resetVars();
  78.         
  79.         if( $isFile === true ) {
  80.             $this->setInputFile($document);
  81.             $result = $this->parse();
  82.         }
  83.         else {
  84.             $result = $this->parseString($document);
  85.         }
  86.         
  87.         if ($this->isError($result)) {
  88.             return $result;
  89.         }
  90.  
  91.         return $this->_struct;
  92.     }
  93.     
  94.     /**
  95.      * Start element handler for XML parser
  96.      *
  97.      * @access protected
  98.      * @param  object $parser  XML parser object
  99.      * @param  string $element XML element
  100.      * @param  array  $attribs attributes of XML tag
  101.      * @return void
  102.      */
  103.     function startHandler($parser, $element, $attribs)
  104.     {
  105.         $struct = array(
  106.                          "type"     => XML_BEAUTIFIER_ELEMENT,
  107.                          "tagname"  => $element,
  108.                          "attribs"  => $attribs,
  109.                          "contains" => XML_BEAUTIFIER_EMPTY,
  110.                          "depth"    => $this->_depth++,
  111.                          "children" => array()
  112.                       );
  113.  
  114.         array_push($this->_struct,$struct);
  115.     }
  116.  
  117.     /**
  118.      * End element handler for XML parser
  119.      *
  120.      * @access protected
  121.      * @param  object XML parser object
  122.      * @param  string
  123.      * @return void
  124.      */
  125.     function endHandler($parser, $element)
  126.     {
  127.         $struct = array_pop($this->_struct);
  128.         if ($struct["depth"] > 0) { 
  129.             $parent = array_pop($this->_struct);
  130.             array_push($parent["children"], $struct);
  131.             $parent["contains"] = $parent["contains"] | XML_BEAUTIFIER_ELEMENT;
  132.             array_push($this->_struct, $parent);
  133.         } else {
  134.             array_push($this->_struct, $struct);
  135.         }
  136.         $this->_depth--;
  137.     }
  138.  
  139.     /**
  140.      * Handler for character data
  141.      *
  142.      * @access protected
  143.      * @param  object XML parser object
  144.      * @param  string CDATA
  145.      * @return void
  146.      */
  147.     function cdataHandler($parser, $cdata)
  148.     {
  149.         if ((string)$cdata === '') {
  150.             return true;
  151.         }
  152.  
  153.         $struct = array(
  154.                          "type"  => XML_BEAUTIFIER_CDATA,
  155.                          "data"  => $cdata,
  156.                          "depth" => $this->_depth
  157.                        );
  158.  
  159.         $this->_appendToParent($struct);
  160.     }
  161.  
  162.     /**
  163.      * Handler for processing instructions
  164.      *
  165.      * @access protected
  166.      * @param  object XML parser object
  167.      * @param  string target
  168.      * @param  string data
  169.      * @return void
  170.      */
  171.     function    piHandler($parser, $target, $data)
  172.     {
  173.         $struct = array(
  174.                          "type"    => XML_BEAUTIFIER_PI,
  175.                          "target"  => $target,
  176.                          "data"    => $data,
  177.                          "depth"   => $this->_depth
  178.                        );
  179.  
  180.         $this->_appendToParent($struct);
  181.     }
  182.     
  183.     /**
  184.      * Handler for external entities
  185.      *
  186.      * @access protected
  187.      * @param  object XML parser object
  188.      * @param  string target
  189.      * @param  string data
  190.      * @return void
  191.      */
  192.     function entityrefHandler($parser, $open_entity_names, $base, $system_id, $public_id)
  193.     {
  194.         $struct = array(
  195.                          "type"    => XML_BEAUTIFIER_ENTITY,
  196.                          "name"    => $open_entity_names,
  197.                          "depth"   => $this->_depth
  198.                        );
  199.  
  200.         $this->_appendToParent($struct);
  201.         return true;
  202.     }
  203.  
  204.     /**
  205.      * Handler for all other stuff
  206.      *
  207.      * @access protected
  208.      * @param  object XML parser object
  209.      * @param  string data
  210.      * @return void
  211.      */
  212.     function defaultHandler($parser, $data)
  213.     {
  214.         switch ($this->_mode) {
  215.             case "xml":
  216.                 $this->_handleXMLDefault($data);
  217.                 break;
  218.             case "doctype":
  219.                 $this->_handleDoctype($data);
  220.                 break;
  221.         }
  222.     }
  223.  
  224.    /**
  225.     * handler for all data inside the doctype declaration
  226.     *
  227.     * @access private
  228.     * @param  string    data
  229.     * @todo   improve doctype parsing to split the declaration into seperate tokens
  230.     */
  231.     function _handleDoctype($data)
  232.     {
  233.         if (eregi(">", $data)) {
  234.             $last = $this->_getLastToken();
  235.             if ($last["data"] == "]" ) {
  236.                 $this->_mode = "xml";
  237.             }
  238.         }
  239.  
  240.         $struct = array(
  241.                          "type"    => XML_BEAUTIFIER_DT_DECLARATION,
  242.                          "data"    => $data,
  243.                          "depth"   => $this->_depth
  244.                        );
  245.         $this->_appendToParent($struct);
  246.     }
  247.     
  248.    /**
  249.     * handler for all default XML data
  250.     *
  251.     * @access private
  252.     * @param  string    data
  253.     */    
  254.     function _handleXMLDefault($data)
  255.     {
  256.         /*
  257.         * handle comment
  258.         */
  259.         if (strncmp("<!--", $data, 4) == 0) {
  260.         
  261.             $regs = array();
  262.             eregi("<!--(.+)-->", $data, $regs);
  263.             $comment = trim($regs[1]);
  264.             
  265.             $struct = array(
  266.                              "type"    => XML_BEAUTIFIER_COMMENT,
  267.                              "data"    => $comment,
  268.                              "depth"   => $this->_depth
  269.                            );
  270.         /*
  271.         * handle XML declaration
  272.         */
  273.         } elseif (strncmp("<?", $data, 2) == 0) {
  274.             preg_match_all('/([a-zA-Z_]+)="((?:\\\.|[^"\\\])*)"/', $data, $match);
  275.             $cnt = count($match[1]);
  276.             $attribs = array();
  277.             for ($i = 0; $i < $cnt; $i++) {
  278.                 $attribs[$match[1][$i]] = $match[2][$i];
  279.             }
  280.  
  281.             if (!isset($attribs["version"])) {
  282.                 $attribs["version"] = "1.0";
  283.             }
  284.             if (!isset($attribs["encoding"])) {
  285.                 $attribs["encoding"] = "UTF-8";
  286.             }
  287.             if (!isset($attribs["standalone"])) {
  288.                 $attribs["standalone"] = true;
  289.             }
  290.             
  291.             $struct = array(
  292.                              "type"       => XML_BEAUTIFIER_XML_DECLARATION,
  293.                              "version"    => $attribs["version"],
  294.                              "encoding"   => $attribs["encoding"],
  295.                              "standalone" => $attribs["standalone"],
  296.                              "depth"      => $this->_depth
  297.                            );
  298.         } elseif (eregi("^<!DOCTYPE", $data)) {
  299.             $this->_mode = "doctype";
  300.             $struct = array(
  301.                              "type"    => XML_BEAUTIFIER_DT_DECLARATION,
  302.                              "data"    => $data,
  303.                              "depth"   => $this->_depth
  304.                            );
  305.         } else {
  306.         /*
  307.         * handle all other data
  308.         */
  309.             $struct = array(
  310.                              "type"    => XML_BEAUTIFIER_DEFAULT,
  311.                              "data"    => $data,
  312.                              "depth"   => $this->_depth
  313.                            );
  314.         }
  315.         
  316.         $this->_appendToParent($struct);
  317.         return true;
  318.     }
  319.     
  320.     /**
  321.      * append a struct to the last struct on the stack
  322.      *
  323.      * @access private
  324.      * @param  array    $struct structure to append
  325.      */
  326.     function _appendToParent($struct)
  327.     {
  328.         if ($this->_depth > 0) {
  329.             $parent = array_pop($this->_struct);
  330.             array_push($parent["children"], $struct);
  331.             $parent["contains"] = $parent["contains"] | $struct["type"];
  332.             array_push($this->_struct, $parent);
  333.             return true;
  334.         }
  335.         array_push($this->_struct, $struct);
  336.     }
  337.  
  338.    /**
  339.     * get the last token
  340.     *
  341.     * @access   private
  342.     * @return   array
  343.     */
  344.     function _getLastToken()
  345.     {
  346.         $parent = array_pop($this->_struct);
  347.         if (isset($parent["children"]) && is_array($parent["children"])) {
  348.             $last = array_pop($parent["children"]);
  349.             array_push($parent["children"], $last);
  350.         } else {
  351.             $last = $parent;
  352.         }
  353.         array_push($this->_struct, $parent);
  354.            
  355.         return $last;
  356.     }
  357.     
  358.    /**
  359.     * reset all used object properties
  360.     *
  361.     * This method is called before parsing a new document
  362.     *
  363.     * @access private
  364.     */
  365.     function _resetVars()
  366.     {
  367.         $this->_depth  = 0;
  368.         $this->_struct = array();
  369.         $this->_mode   = "xml";
  370.     }
  371. }
  372. ?>